package araujoCoronelVillamayor.plantasVsZombies.domain

import java.util.List
import org.uqbar.commons.utils.Observable
import java.util.ArrayList
import araujoCoronelVillamayor.plantasVsZombies.appModelsArena.SesionAppModel
import java.io.Serializable

@Observable
class Ataque implements Serializable {
	
	@Property List<AtaqueLog> coleccionDeLogs
	@Property SesionAppModel sesionAppModel
	Zombie zombie
	Fila fila
	
	new(Zombie zombieParametro, Fila filaParametro, SesionAppModel sesionAppModelParametro){
		zombie = zombieParametro
		fila = filaParametro
		sesionAppModel = sesionAppModelParametro
		coleccionDeLogs = new ArrayList<AtaqueLog>
	}

	def loopDeAtaque(){

		while (fila.hayPlantas && zombie.tieneVida){

			crearLogPreAtaque(zombie, fila.ultimaPlanta)
			zombie.ataca(fila.ultimaPlanta)
			crearLogPostAtaque(zombie, fila.ultimaPlanta)

			//Si la planta vive, ataca al zombie
			if (fila.ultimaPlanta.tieneVida){
				crearLogPreAtaque(fila.ultimaPlanta, zombie)
				fila.ultimaPlanta.ataca(zombie)
				crearLogPostAtaque(fila.ultimaPlanta, zombie)

//				if (!zombie.tieneVida){
//					crearLogMuerte(zombie)
//					crearLogGanador(fila.ultimaPlanta)
//				}
			}
			//Si la planta murió, hay que sacarla de la fila y verificar si quedan plantas en la fila.
			else{
				crearLogMuerte(fila.ultimaPlanta)
				crearLogGanador(zombie)				
				fila.quitarPlanta(fila.ultimaPlanta)
			}

			//Evaluar resultados del ataque
			this.evaluarResultadosAtaque(fila, zombie)
		}
	}

	def void evaluarResultadosAtaque(Fila fila, Zombie zombie){
		//Si no quedan plantas en la fila entonces el zombie llegó a la meta. Pierde el jugador.
		if(!fila.hayPlantas){
			crearLogLlegoAMeta(zombie)
		}

		//Si murió el zombie hay que agregar recursos a la sesión.
		if(!zombie.tieneVida){
			crearLogMuerte(zombie)
			crearLogGanador(fila.ultimaPlanta)
			this.entregarPremio(zombie)
			sesionAppModel.ataqueAppModel.zombies.remove(zombie)
			crearLogEntregaDePremio(zombie)		
		}
	}
	
	def void entregarPremio(Zombie zombie){
		sesionAppModel.agregarRecursos(zombie.premio)
	}
	
	def void crearLogLlegoAMeta(Zombie zombie){
		val ataqueLogPaso = new AtaqueLog()
		ataqueLogPaso.generarFinalLog(zombie)
		coleccionDeLogs.add(ataqueLogPaso)
	}

	def void crearLogEntregaDePremio(Zombie zombie){
		val ataqueLogPaso = new AtaqueLog()
		ataqueLogPaso.generarEntregaPremio(zombie)
		coleccionDeLogs.add(ataqueLogPaso)
	}
	
	def void crearLogPreAtaque(Criatura atacante, Criatura victima){
		val ataqueLogRegistro = new AtaqueLog()
		ataqueLogRegistro.generarPreAtaqueLog(atacante, victima)
		coleccionDeLogs.add(ataqueLogRegistro)
	}

	def void crearLogPostAtaque(Criatura atacante, Criatura victima){
		val ataqueLogRegistro = new AtaqueLog()
		ataqueLogRegistro.generarPostAtaqueLog(atacante, victima)
		coleccionDeLogs.add(ataqueLogRegistro)
	}
	
	def void crearLogMuerte(Criatura muerto){
		val ataqueLogRegistro = new AtaqueLog()
		ataqueLogRegistro.generarMuerteLog(muerto)
		coleccionDeLogs.add(ataqueLogRegistro)
	}

	def void crearLogGanador(Criatura ganador){
		val ataqueLogRegistro = new AtaqueLog()
		ataqueLogRegistro.generarGanadorLog(ganador)
		coleccionDeLogs.add(ataqueLogRegistro)
	}
}